import {getCartList,addToCart,checkCart,deleteCart} from "api/api"
import router from "router/router"
import {Message} from 'element-ui';
export default {
    state:{
        cartList:[]
    },
    getters:{
        //购物车中的商品
        cartInfoList(state){
            if(state.cartList[0]){
                return state.cartList[0].cartInfoList
            }else {
                return []
            }
        },
        //代表购物车列表界面的全选按钮是否该选中
        checkAll(state,getters){
            //如果列表为空 全选不能选中
            //getters: 当前全局的getters
            if(getters.isEmpty){return false}
            //不为空的逻辑
            let checked = true;
            state.cartList[0] && state.cartList[0].cartInfoList.forEach(item=>{
                if (item.isChecked !== 1){
                    checked = false;
                    return ;
                }
            })
            return checked;
        },
        //购物车是否为空
        isEmpty(state){
            if(state.cartList.length===0){return true}
            if(state.cartList[0].cartInfoList.length===0){return true}
            return false;
        },
        //购物车中商品的总数量
        totalNum(state,getters){
           return getters.cartInfoList.reduce((adder,item)=>{
                if(item.isChecked === 1){
                    //选中商品
                    return adder + item.skuNum
                }else {
                    return adder
                }
            },0)
        },
        //购物车中商品的总价
        totalPrice(state,getters){
            return getters.cartInfoList.reduce((adder,item)=>{
                if(item.isChecked === 1){
                    //选中商品
                    return adder + (item.skuPrice * item.skuNum)
                }else {
                    return adder
                }
            },0)
        }
    },
    mutations:{
        //获取购物车列表
        getCartList(state,cartList){
            state.cartList = cartList;
        },
        //勾选商品
        checkedChange(state,{skuId,checked}){
           if(state.cartList[0] && state.cartList[0].cartInfoList){
               state.cartList[0].cartInfoList.filter(item=>item.skuId === skuId)[0].isChecked = checked
           }
        },
        //删除商品
        deleteCart(state,skuId){
            if(state.cartList[0] && state.cartList[0].cartInfoList){
                state.cartList[0].cartInfoList =
                    state.cartList[0].cartInfoList.filter(item=>item.skuId !== skuId)
            }
        }
    },
    actions:{
        //添加购物车
        async addToCartForShopcart(store,{skuId,skuNum}){
            try {
                const {code} = await addToCart({skuId,skuNum})
                return code;
            }catch (err){
                return Promise.reject(err)
            }
        },
        //删除商品(删除选中)
        deleteChecked(store){
            store.getters.cartInfoList.forEach(item=>{
                if(item.isChecked === 1){
                    //选中商品
                   store.dispatch("deleteCart",item.skuId)
               }
            })
        },
        //删除商品(单删)
        async deleteCart(store,skuId){
            const {code} = await deleteCart(skuId)
            if(code===200){
                //也可以调用mutation来完成操作!
                store.commit("deleteCart",skuId)
            }
        },
        //勾选商品(全选)  最好的设计应该是后台提供全选的接口
        async checkedAll(store,checked){
            const arr =[];
            store.getters.cartInfoList.forEach(item=>{
                //发N次请求!!! 得看有多少个购物车商品! 最好的设计应该是后台提供全选的接口
                //如果有10条数据 前五条请求成功了 后五条请求没成功!!!  无法保证操作的一致性
                //如果有后台接口 后台可以进行事务操作 保证操作的一致性 要么一起成功 要么一起失败
                arr.push(store.dispatch("checkedChange",{skuId:item.skuId,checked}))
            })
            const res = await Promise.all(arr);

            //因为单选中将重新获取数据库中数据选中状态的代码移到了组件中 所以全选的时候需要重新在调一把
            await store.dispatch("getCartList");

            const flag = res.every((item)=>{
                return item === 200
            })
            return flag  ? 200:400
        },
        //勾选商品(单选)
        async checkedChange(store,{skuId,checked}){
            //发送请求修改数据库 成功之后 更新mutation
            //发请求改掉了数据库中的选中状态

            /* 第一版  我们的请求本质是成功的 选中操作是成功的!
                const {code} = await checkCart({skuId,isChecked:checked?1:0})
                if(code===200){
                    store.commit("checkedChange",{skuId,checked});
                }
            */

            //当接口需要的数据传递错误时  我们的请求本质是成功的 当时对于这个业务逻辑来讲这个操作是失败的!
            /*第二版 处理我们的请求本质是成功的 选中操作是失败的状况
            const {code} = await checkCart({skuId,isChecked:checked?1:0});
            store.commit("checkedChange",{skuId,checked});
            if(code!==200){
                Message.error("勾选失败")
            }
            //将数据库中的数据重新请求回来!!! 一切以数据库为准
            await store.dispatch("getCartList");*/


            /*第三版 处理我们的请求本质是失败的状况 让外部组件页接收到当前请求的状态*/
            try {
                const {code} = await checkCart({skuId,isChecked:checked?1:0});
                store.commit("checkedChange",{skuId,checked});
                if(code!==200){
                    Message.error("勾选失败")
                }
                //将数据库中的数据重新请求回来!!! 一切以数据库为准
                //await store.dispatch("getCartList");
                return code
            }catch (err){
                //1. 网络问题
                //2. 接口地址写错! 404
                Message.error("网络异常 操作无效")
                return 400
            }
        },
        //添加购物车 skuNum:增量!
        async addToCart(store,{skuId,skuNum}){
            try {
                const {code} = await addToCart({skuId,skuNum})
                if (code === 200){
                    window.sessionStorage.setItem("goodInfo",JSON.stringify({
                        skuInfo:store.getters.skuInfo,
                        checkedGoodsAttr:store.getters.checkedGoodsAttr
                    }))
                    await router.push(`/addCartSuccess?skuNum=${skuNum}`);
                }else{
                    this.$message.error('添加购物车失败哦!');
                }
            }catch (err){
                this.$message.error('网络问题!错了哦!');
            }
        },
        //获取购物车列表
        async getCartList(store){
            const {code,data} = await getCartList();
            if(code === 200){
                store.commit("getCartList",data);
                return data;
            }
        }
    }
}